package com.village.friend.pay.wechat;

import com.alibaba.fastjson.JSON;
import com.village.friend.constant.MsgCodeEnum;
import com.village.friend.constant.PayStatus;
import com.village.friend.dto.response.BaseResponse;
import com.village.friend.entity.UserOrder;
import com.village.friend.pay.Product;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

@Slf4j
@Service
public class WxPayServiceImpl {
    @Autowired
    private WXConfig config;

    public BaseResponse<Map<String, String>> wxPay(Product product) {
        log.info("微信手机支付下单");
        try {
            WXPay wxpay;
            log.info("支付应用名称:" + config.getAppID());
            wxpay = new WXPay(config);
            int totalFee = new BigDecimal(product.getTotalFee()).multiply(new BigDecimal(100)).intValue();
            Map<String, String> data = new HashMap<String, String>();
            data.put("body", product.getBody());
            data.put("out_trade_no", product.getOutTradeNo());
            data.put("fee_type", "CNY");
            data.put("total_fee", String.valueOf(totalFee));
            data.put("spbill_create_ip", product.getIp());
            data.put("notify_url", config.getNotifyUrl());
            data.put("trade_type", "APP");  // 此处指定为扫码支付
            log.info("微信支付参数:" + JSON.toJSONString(data));
            Map<String, String> resp = wxpay.unifiedOrder(data);
            log.info("微信支付返回:" + JSON.toJSONString(resp));
            if (resp.get("return_code").equals(WXPayConstants.SUCCESS)) {
                Map<String, String> params = new HashMap<String, String>();
                params.put("appid", resp.get("appid"));
                params.put("partnerid", resp.get("mch_id"));
                params.put("prepayid", resp.get("prepay_id"));
                params.put("noncestr", resp.get("nonce_str"));
                params.put("package", "com.ourteam.hello.feel");
                params.put("timestamp", String.valueOf(System.currentTimeMillis() / 1000));
                String sign = WXPayUtil.generateSignature(params, config.getKey());
                params.put("sign", sign);
                return new BaseResponse(MsgCodeEnum.SUCCESS, params);
            }

        } catch (Exception e) {
            log.error("wxPay_err=", e);
        }

        return new BaseResponse(MsgCodeEnum.OTHER_ERROR,"支付失败");
    }

    /**
     * 微信查单
     *
     * @param order
     */
    public void wxQuery(UserOrder order) {
        try {
            log.info("查询订单状态: " + JSON.toJSONString(order));
            WXPay wxpay = new WXPay(config);
            Map<String, String> reqDate = new HashMap<>();
            reqDate.put("out_trade_no", order.getId());
            Map<String, String> respMap = wxpay.orderQuery(reqDate);
            log.info("微信订单查询结果: " + JSON.toJSONString(respMap));
            String code = respMap.get("return_code");
            if ("SUCCESS".equalsIgnoreCase(code)) {
                if ("SUCCESS".equalsIgnoreCase(respMap.get("result_code"))) {
                    String state = respMap.get("trade_state");
                    //SUCCESS--支付成功
                    //REFUND--转入退款
                    //NOTPAY--未支付
                    //CLOSED--已关闭
                    //REVOKED--已撤销(刷卡支付)
                    //USERPAYING--用户支付中
                    //PAYERROR--支付失败(其他原因，如银行返回失败)
                    //ACCEPT--已接收，等待扣款
                    switch (state) {
                        case "SUCCESS":
                            order.setPayStatus(PayStatus.SUCCESS.getValue());
                            break;
                        case "USERPAYING":
                        case "ACCEPT":
                            order.setPayStatus(PayStatus.IN_PROCESS.getValue());
                            break;
                        default:
                            order.setPayStatus(PayStatus.FAILED.getValue());
                            order.setFailedReason(state2Desc(state));
                            break;
                    }
                } else {
                    order.setPayStatus(PayStatus.FAILED.getValue());
                    String codeDes = respMap.get("err_code_des");
                    order.setFailedReason(codeDes);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private String state2Desc(String state) {
        //SUCCESS--支付成功
        //REFUND--转入退款
        //NOTPAY--未支付
        //CLOSED--已关闭
        //REVOKED--已撤销(刷卡支付)
        //USERPAYING--用户支付中
        //PAYERROR--支付失败(其他原因，如银行返回失败)
        //ACCEPT--已接收，等待扣款
        switch (state) {
            case "SUCCESS":
                return "支付成功";
            case "USERPAYING":
                return "用户支付中";
            case "REFUND":
                return "转入退款";
            case "NOTPAY":
                return "未支付";
            case "CLOSED":
                return "已关闭";
            case "REVOKED":
                return "已撤销(刷卡支付)";
            case "ACCEPT":
                return "已接收，等待扣款";
            case "PAYERROR":
                return "支付失败(其他原因，如银行返回失败)";
            default:
                return "未知的状态:" + state;
        }
    }
}
